package org.duang.pay.utils;

import java.net.InetAddress;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.duang.kit.ToolsKit;
import org.duang.pay.security.Base64;
import org.duang.pay.security.MD5;


public class SignUtils {
	
	private static String intranetIp;
	
	public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
	public static final String  SIGN_TYPE_RSA = "RSA";
	
	public static String signRSA(String content, String privateKey, String charset) {
		// String charset = "utf-8";
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
			KeyFactory keyf = KeyFactory.getInstance(SIGN_TYPE_RSA);
			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
			signature.initSign(priKey);
			signature.update(content.getBytes(charset));
			byte[] signed = signature.sign();
			return Base64.encode(signed);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	public static String signMD5(String content, String privateKey, String input_charset) {
		String paramsStringTmp = content + "&key="+privateKey;
        return MD5.MD5Encode(paramsStringTmp).toUpperCase();
	}
	
	
	public static String buildSign(Map<String, Object> sPara, String signType, String key, String charset) {
    	String prestr = createLinkString(sPara); //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        String mysign = "";
        if("MD5".equalsIgnoreCase(signType) ) {
        	mysign = signMD5(prestr, key, charset);
        } else  if("RSA".equalsIgnoreCase(signType) ) {
        	mysign = signRSA(prestr, key, charset);
        }
        return mysign;
    }
	
	public static String createLinkString(Map<String, Object> map) {
		Map<String,String> paramMap = paraFilter(map);
		 List<String> keys = new ArrayList<String>(paramMap.keySet());
		    Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
		    StringBuilder prestr = new StringBuilder();
		    int size = keys.size();
		    for (int i = 0; i < size; i++) {
		        String key = keys.get(i);		        
		        prestr.append(key).append("=").append(paramMap.get(key).toString()).append("&");
		    }
		    if(prestr.length() > 1) {
		    	prestr = prestr.deleteCharAt(prestr.length()-1);
		    }
		    return prestr.toString();
	}
	
	public static String createLinkJsonString(Map<String, Object> map) {
		Map<String,String> paramMap = paraFilter(map);
		Map<String, String> result = new HashMap<String, String>();
		List<String> keys = new ArrayList<String>(paramMap.keySet());
	    Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
	    int size = keys.size();
	    for (int i = 0; i < size; i++) {
	        String key = keys.get(i);
	        result.put(key, paramMap.get(key));
	    }
	    return ToolsKit.toJsonString(result);
	}
	
	 /** 
     * 除去集合中的空值和签名参数
     * @param sArray 签名参数组
     * @return 去掉空值与签名参数后的新签名参数组
     */
    private static Map<String, String> paraFilter(Map<String, Object> sArray) {

        Map<String, String> result = new HashMap<String, String>();

        if (sArray == null || sArray.size() <= 0) {
            return result;
        }

        for (String key : sArray.keySet()) {
            String value = sArray.get(key)+"";            
            if (ToolsKit.isEmpty(value) || key.equalsIgnoreCase("sign")
                || key.equalsIgnoreCase("sign_type")) {
                continue;
            }
            result.put(key, value);
        }

        return result;
    }
    

	/**
	 * 获取本机的局域网IP。
	 */
	public static String getIntranetIp() {
		if (intranetIp == null) {
			try {
				intranetIp = InetAddress.getLocalHost().getHostAddress();
			} catch (Exception e) {
				intranetIp = "127.0.0.1";
			}
		}
		return intranetIp;
	}
}

